#pragma once

#include "..\\headers.default.h"
#include "..\\headers.cv.h"

#include "NodeInstance.h"
#include "AbstractTree.h"

using namespace loirey;

namespace and_or_tree
{
	class CTreeInstance
	{
	public:
		int Para_GenPixelCandidate_PixMargin;
		double Para_GenPixelCandidate_PixSampleRate;
	public:
		const CAbstractTree* pTree;
	public:
		CImg<int> imgSrcRGB;
		CImageFilterBank* pIFB;
		CImagePyramidPositionFeatureExtractor* pIPPFE_Leaf;
		bool fIsIPPFEshared;
	public:
		int W, H;
		int WH;
		const double* OrientationList;
		const double* EdgeMap;
	public:
		CSimpleTypeArray<int> NearestCandidatePixelList;
		CSimpleTypeArray<int> CandidatePixelList;
	public:
		CSimpleTypeArray<CParsedInstance> ParsedInstanceList;
		CSimpleTypeArray<CSimpleTypeArray<CInstanceChoice>> InstanceSet;

	private:
		void __Init_IBF_and_IPPFE();
	public:
		void SetPixelCandidateGeneratingParameters(int PixMargin, double PixSampleRate);
	protected:
		void myRelease();
	public:
		CTreeInstance();
		~CTreeInstance();
		CTreeInstance(const CTreeInstance& AnotherIntance);
		CTreeInstance& operator = (const CTreeInstance& AnotherIntance);
		void ShareIPPFE_From(const CTreeInstance& AnotherIntance);
		void CloneDataFrom(const CTreeInstance& AnotherInstance, bool fShareIPPFE);
	public:
		void InitTree(const CAbstractTree* pFixedAndOrTree);
		void ClearAllInstances();
	public:
		CSimpleTypeArray<CInstanceChoice>& GetInstanceList(int NodeIndex);
		CInstanceChoice& GetInstance(int NodeIndex, int InstanceIndex);
		const CSimpleTypeArray<CInstanceChoice>& GetInstanceList(int NodeIndex) const;
		const CInstanceChoice& GetInstance(int NodeIndex, int InstanceIndex) const;
	public:
		void ClearImage();
		void InitImage(const CImg<int>& imgSrcRGB);
		void InitImage(string strFN_Image);
		void InitParsedImage(string strFN_ParsedResult);
	public:
		void GenerateCandidatePixelList();
		void DrawCandidatePixelList(CImg<int>& imgDstRGB) const;
	public:
		void BuildPixelInstance(CParsedInstance* pDstInstance, bool fShouldBeCandiate, int xy) const;
		void BuildPixelInstance(CParsedInstance* pDstInstance, bool fShouldBeCandiate, double x, double y) const;
	public:
		//void ExtractBasicInstancePtrList(CSimpleTypeArray<const CBasicInstance*>& DstBiptrList, int NodeIndex) const;
		//void ExtractBasicInstancePtrList(CSimpleTypeArray<const CBasicInstance*>& DstBiptrList, int NodeIndex, const int* pSrcChoiceIndex) const;
		void ExtractParsedInstancePtrList(CSimpleTypeArray<const CParsedInstance*>& DstPiptrList, int NodeIndex) const;
		void ExtractParsedInstancePtrList(CSimpleTypeArray<const CParsedInstance*>& DstPiptrList, int NodeIndex, const int* pSrcChoiceIndex) const;
	public:
		void RefreshNodeShapeScore(double NewNodeShapeScore, int NodeIndex, CParsedInstance* pDstParsedInstance) const;
		void RefreshNodeShapeScore(double NewNodeShapeScore, int NodeIndex, CInstanceChoice* pDstInstanceChoice) const;
		void RefreshNodeAppearanceScore(double NewNodeAppearanceScore, int NodeIndex, CParsedInstance* pDstParsedInstance) const;
		void RefreshNodeAppearanceScore(double NewNodeAppearanceScore, int NodeIndex, CInstanceChoice* pDstInstanceChoice) const;
		void RefreshNodeTotalScore(double NewNodeShapeScore, double NewNodeAppearanceScore, int NodeIndex, CParsedInstance* pDstParsedInstance) const;
		void RefreshNodeTotalScore(double NewNodeShapeScore, double NewNodeAppearanceScore, int NodeIndex, CInstanceChoice* pDstInstanceChoice) const;
		//void RefreshNodeShapeScore(double NewNodeShapeScore, int NodeIndex);
		//void RefreshNodeShapeScore(double NewNodeShapeScore, int NodeIndex, int ChoiceIndex);
		//void RefreshNodeAppearanceScore(double NewNodeAppearanceScore, int NodeIndex);
		//void RefreshNodeAppearanceScore(double NewNodeAppearanceScore, int NodeIndex, int ChoiceIndex);
		//void RefreshNodeTotalScore(double NewNodeShapeScore, double NewNodeAppearanceScore, int NodeIndex);
		//void RefreshNodeTotalScore(double NewNodeShapeScore, double NewNodeAppearanceScore, int NodeIndex, int ChoiceIndex);
	public:
		void SetMe_AT_CAbstractTree() const;
	public:
		void ComputeNodeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			int NodeIndex, const CParsedInstance* pParsedInstance
			) const;
		void ComputeNodeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			int NodeIndex, const CInstanceChoice* pInstanceChoice
			) const;
		void ComputeTreeParsedInstanceShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList
			) const;
		void ComputeNodeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			int NodeIndex, const CParsedInstance* pParsedInstance
			) const;
		void ComputeNodeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			int NodeIndex, const CInstanceChoice* pInstanceChoice
			) const;
		void ComputeTreeParsedInstanceAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList
			) const;
		void ComputeNodeFullFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			int NodeIndex, const CParsedInstance* pParsedInstance
			) const;
		void ComputeNodeFullFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			int NodeIndex, const CInstanceChoice* pInstanceChoice
			) const;
		void ComputeTreeParsedInstanceFullFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			CSimpleTypeArray<double>& DstAppearanceFeatureList
			) const;
	public:
		void DrawWhiteImage(CImg<int>& imgDstRGB) const;
		void DrawPoint(CImg<int>& imgDstRGB, int x, int y, int sqr_radius, int RGB) const;
		void DrawParsedImage(CImg<int>& imgDstRGB, double FullTreeScore) const;
		void DrawParsedImage(CImg<int>& imgDstRGB) const;
		void DrawNodeInstanceChoiceSet(CImg<int>& imgDstRGB, int NodeIndex, bool fDrawFakeInstances) const;
	public:
		bool ParseFromTop(int RootChoiceIndex);
	protected:
		void _ParseFromTop(int NodeIndex, int ChoiceIndex, int* pNodeVisitAmount);

	public:
		void OutputSizeInformation(ostream& outStream = cout) const;

	//public:
	//	void Parse_old_FromTop(int NodeIndex, int ChoiceIndex);
	//	void TagUsefulInstanceChoicesFromTop(int NodeIndex, int ChoiceIndex);
	//	void GetSingleTreeInstance(CSimpleTypeArray<C_old_InstanceChoice*>& DstInstancePtrList, int RootChoiceIndex) const;
	//	void DrawParsedImage(CImg<int>& imgDstRGB, double FullTreeScore) const;
	//	void DrawParsedImage(CImg<int>& imgDstRGB) const;
	//protected:
	//	void _GetSingleTreeInstance(CSimpleTypeArray<_C_old_InstanceChoicePointer>& Dst_ICP_List, int NodeIndex, int ChoiceIndex) const;
	//private:
	//	void __Parse_old_FromTop(int NodeIndex, int ChoiceIndex, CSimpleTypeArray<C_old_NodeInstance>* matNodeInstance);
	//	void __TagUsefulInstanceChoicesFromTop(int NodeIndex, int ChoiceIndex);
	};
}

